home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / gp / encode.c < prev    next >
C/C++ Source or Header  |  1991-12-21  |  12KB  |  386 lines

  1. #include "7plus.h"
  2. #include "globals.h"
  3.  
  4. /*
  5. *** encode a file. split, if desired/needed. create correction file.
  6. ***
  7. ***
  8.  */
  9.  
  10. int encode_file (char *name, long blocksize, char *searchbin)
  11. {
  12.   int      part, parts, blockzeilen, lfd_zeile;
  13.   int      correct, corrzeilen, corrpart, corrzeile;
  14.   uint     csequence;
  15.   ulong    danach[16], *dn, h;
  16.   long     binbytes, binb0, position, size;
  17.   char     destname[13], hdrname[MAXFNAME], filename[13], corrname[13];
  18.   char     orgname[66], inpath[MAXFPATH], zeile[81], zeile2[81];
  19.   char     dummi[20], dummi2[20], *q, *r;
  20.   FILE     *rein, *raus, *corr;
  21.   register i, j, k;
  22.  
  23.   correct = i = 0;
  24.   *destname = *hdrname = *filename = *corrname = *inpath = *orgname = EOS;
  25.   *_file = EOS;
  26.   raus = NULL;
  27.  
  28.  
  29.   if (fls)
  30.     if (!test_exist ("7plus.fls"))
  31.       unlink ("7plus.fls");
  32.  
  33.   if (searchbin)
  34.   {
  35.     /* Get serchpath for binary (original) file. */
  36.     fnsplit (searchbin, _drive, _dir, _file, _ext);
  37.     sprintf (inpath, "%s%s", _drive, _dir);
  38.   }
  39.  
  40.   q = name;
  41.   /* create correction file, if ext of input file is .ERR */
  42.   if ((r = strrchr (q, '.')) != NULL)
  43.     if (!strnicmp (".err", r, 4))
  44.     {
  45.       /* OK, input file is an error file */
  46.       correct = 1;
  47.  
  48.       if (crc_file (q, "7PLUS error", "00\n", 1) == 1)
  49.         return (7);
  50.  
  51.       corr = fopen (q, OPEN_READ_TEXT);
  52.  
  53.       /* Find starting line. */
  54.       while ((r = my_fgets (zeile, 80, corr)) != NULL)
  55.         if (!strncmp (zeile, "7PLUS ", 6))
  56.           break;
  57.       if (!r)
  58.       {
  59.         printf ("\007'%s': invalid error report. Break.\n", q);
  60.         fclose (corr);
  61.         return (7);
  62.       }
  63.       /* Get name, lines per part, and length of original file from error file.*/
  64.       *orgname = EOS;
  65.       binb0 = 0L;
  66.       sscanf (zeile+20, "%12s %s /%66[^/]/ %ld",
  67.                                          corrname, dummi, orgname, &binb0);
  68.       corrzeilen = get_hex (dummi);
  69.       if (!*orgname)
  70.       {
  71.         binb0 = 0L;
  72.         sscanf (zeile+20, "%s %s %ld", dummi, dummi, &binb0);
  73.       }
  74.       strlwr (corrname);
  75.       if (extended != '*' || !*orgname)
  76.         strcpy (orgname, corrname);
  77.       /* Build complete filename for original file */
  78.       if (!*_file)
  79.         strcat (inpath, orgname);
  80.       else
  81.       {
  82.         strcat (inpath, _file);
  83.         strcat (inpath, _ext);
  84.       }
  85.       q = inpath;
  86.     }
  87.  
  88.   if ((rein = fopen (q, OPEN_READ_BINARY)) == NULL)
  89.   {
  90.     printf ("\007'%s' not found. Break.\n", q);
  91.     return (2);
  92.   }
  93.  
  94.   /* determine size of original file. This could be done with filestat(),
  95.      but it's not available on all compilers. */
  96.   fseek (rein, 0L, SEEK_END); /* position read pointer to end of file. */
  97.   size = ftell (rein);        /* get size. */
  98.   fseek (rein, 0L, SEEK_SET); /* reposition to beginning of file. */
  99.  
  100.   if (correct && binb0 && size != binb0)
  101.   {
  102.     printf (notsame, "error report");
  103.     return (15);
  104.   }
  105.  
  106.   part = parts = 1;
  107.  
  108.   if (!correct)
  109.   {
  110.     /* Bufferize input, if we're encoding. */
  111.     setvbuf (rein, NULL, _IOFBF, buflen);
  112.  
  113.     /* if blocksize is greater then try to split into blocksize-50000 parts */
  114.     if (blocksize > 50000L)
  115.     {
  116.       blocksize -= 50000L;
  117.       /* calculate how many assci-bytes per part are needed to get roughly
  118.          equal filelengths. */
  119.       blocksize = (((size + 61) / 62) + (blocksize - 1)) / blocksize;
  120.       blocksize *= 62;
  121.     }
  122.  
  123.     /* if blocksize is defined as zero or if it's bigger than the file,
  124.        set it to filelength  */
  125.     if (!blocksize || blocksize > size)
  126.       blocksize = size;
  127.  
  128.     /* automatically split into 512 line parts, if file is bigger. */
  129.     if (blocksize > (512 * 62))
  130.     {
  131.       blocksize = 512 * 62;
  132.       printf ("Blocksize limited to 512 lines per file.\n");
  133.     }
  134.     /* how many lines do the parts contain? */
  135.     blockzeilen = (int) ((blocksize + 61) / 62);
  136.  
  137.     /* how many parts result from that? */
  138.     parts = (int) ((size + blocksize-1) / blocksize);
  139.  
  140.     if (parts > 255)
  141.     {
  142.       printf ("\007Not more than 255 parts allowed.\n");
  143.       printf ("Choose different blocksize. Break.\n");
  144.       return (8);
  145.     }
  146.   }
  147.   /* generate filenames */
  148.   fnsplit (q, NULL, NULL, _file, _ext);
  149.   sprintf (orgname, "%s%s", _file, _ext);
  150.   build_DOS_name (_file);
  151.   build_DOS_name (_ext);
  152.   /* make sure, the name isn't longer than 8 chars
  153.      and extension not longer 4 (including dot). */
  154.   _file[8] = _ext[3] = EOS;
  155.  
  156.   strcpy (destname, _file);
  157.   sprintf (hdrname, "%s%s%s", _file, _ext[0]?".":"", _ext);
  158.   strupr (hdrname);
  159.  
  160.   printf ("\n");
  161.  
  162.   /* encode parts */
  163.   for (part=1; part<parts+1 ; part++)
  164.   {
  165.     if (!correct)
  166.     {
  167.       /* generate output filename. *.7PL, if unsplit. *.PXX if split.
  168.          XX represents a two digit hex number. */
  169.       if (parts == 1)
  170.       {
  171.         sprintf (filename, "%s%s", destname, ".7pl");
  172.         printf ("'%s': Writing.\r", filename);
  173.       }
  174.       else
  175.       {
  176.         sprintf (filename, "%s.p%02x", destname, part);
  177.         printf ("'%s': Writing part %03d of %03d.\r", filename, part, parts);
  178.       }
  179.  
  180.       fflush (stdout);
  181.  
  182.       /* check, if output file already exists. */
  183.       test_file (raus, filename, 0, 12);
  184.     }
  185.     else /* we're creating a correction file, set name accordingly. */
  186.     {
  187.       fnsplit (corrname, NULL, NULL, destname, NULL);
  188.       sprintf (filename, "%s.cor", destname);
  189.     }
  190.     raus = fopen (filename, OPEN_WRITE_TEXT);
  191.     setvbuf (raus, NULL, _IOFBF, buflen);
  192.  
  193.     if (!correct)
  194.     {
  195.       if (part == parts && parts > 1)
  196.       {
  197.         if (size % blocksize)
  198.           blocksize = size % blocksize;
  199.         blocksize = ((blocksize + 61 ) / 62) *62;
  200.       }
  201.       /* output header */
  202.       sprintf (zeile, " go_7+. %03d of %03d %-12s %07ld %04X %03X (7PLUS v1.6) \
  203. \xb0\xb1\xb2%c", part, parts, hdrname, size,
  204.                     (uint)(((blocksize+61)/62) * 64), blockzeilen,
  205.                     extended);
  206.  
  207.       mcrc (zeile, 1);
  208.       add_crc2 (zeile);
  209.       fprintf (raus, "%s%s", zeile, delimit);
  210.  
  211.       if (part == 1 && extended == '*')
  212.       {
  213.         sprintf (zeile, "///////////////////////////////////////////////////\
  214. ///////////\xb0\xb1\xb2*");
  215.         strcpy (zeile+1, orgname);
  216.         zeile[(int)strlen(orgname)+1] = '/';
  217.         mcrc (zeile, 1);
  218.         add_crc2 (zeile);
  219.         fprintf (raus, "%s%s", zeile, delimit);
  220.       }
  221.     }
  222.     else
  223.     {
  224.       /* output correction file header */
  225.       strcpy (dummi2, filename);
  226.       strupr (dummi2);
  227.       fprintf (raus, " go_text. %s%s", dummi2, delimit);
  228.       strupr (corrname);
  229.       fprintf (raus, "7PLUS correction: %s %ld%s", corrname, size, delimit);
  230.       strlwr (corrname);
  231.       fscanf (corr, "%s", dummi2);
  232.       corrpart = get_hex (dummi2);
  233.       fprintf (raus, " P%02x:%s", corrpart, delimit);
  234.     }
  235.  
  236.     lfd_zeile = j = 0;
  237.     binbytes = 0L;
  238.  
  239.     /* get bytes from original file until it ends or blocksize is reached. */
  240.     while (!feof(rein) && ((binbytes < blocksize) || parts == 1))
  241.     {
  242.       csequence = 0;
  243.  
  244.       if (correct)
  245.       {
  246.         /* get number of part and number of line to put into correction file
  247.            from error file */
  248.         fscanf (corr, "%s", dummi2);
  249.         corrzeile = get_hex (dummi2);
  250.         if (corrzeile == 0xfff)
  251.         {
  252.           corrpart = 0;
  253.           fscanf (corr, "%s", dummi2);
  254.           corrpart = get_hex (dummi2);
  255.           if (!corrpart)
  256.             break;
  257.           fprintf (raus, " P%02x:%s", corrpart, delimit);
  258.           fscanf (corr, "%s", dummi2);
  259.           corrzeile = get_hex (dummi2);
  260.         }
  261.         lfd_zeile = corrzeile;
  262.         /* calculate position in original file to get data from. */
  263.         position =  (long)(corrpart-1) * 62 * (long)corrzeilen +
  264.                     62 * (long)corrzeile ;
  265.         /* position read pointer. */
  266.         fseek (rein, position, SEEK_SET);
  267.         fprintf (raus, " L%03X:%s", corrzeile, delimit);
  268.       }
  269.  
  270.       /* get two groups of 31 bytes and stuff them into 2 * 8 longs. */
  271.       dn = danach;
  272.       for (i=0; i<2; i++, dn+=8)
  273.       {
  274.         /* Get 31 Bytes and put them into 8 longs. */
  275.         for(j=0; j<8; j++)
  276.         {
  277.           dn[j] = 0L;
  278.           for (k=(j==7)?2:3; k>-1; k--)
  279.           {
  280.             if ((h = fgetc (rein)) == EOF)
  281.             {
  282.               if (!i && !j && k == 3)
  283.                 i = 255;
  284.               h = 0L;
  285.             }
  286.             dn[j] = (dn[j] << 8) | h;
  287.           }
  288.         }
  289.         /* Rearrange into 8 31bit values. */
  290.         dn[7] =  dn[7]       | ((dn[6] & 127L) << 24);
  291.         dn[6] = (dn[6] >> 7) | ((dn[5] & 63L ) << 25);
  292.         dn[5] = (dn[5] >> 6) | ((dn[4] & 31L ) << 26);
  293.         dn[4] = (dn[4] >> 5) | ((dn[3] & 15L ) << 27);
  294.         dn[3] = (dn[3] >> 4) | ((dn[2] & 7L  ) << 28);
  295.         dn[2] = (dn[2] >> 3) | ((dn[1] & 3L  ) << 29);
  296.         dn[1] = (dn[1] >> 2) | ((dn[0] & 1L  ) << 30);
  297.         dn[0] = (dn[0] >> 1);
  298.       }
  299.       /* i is 256, then no bytes were read. End of file. */
  300.       if (i == 256)
  301.         break;
  302.  
  303.       binbytes += 62;
  304.  
  305.       /* write code line to output file. do radix216 conversion, crc
  306.          calculation and ascii conversion as we go along. */
  307.       for (i=j=0;i<16;i++)
  308.       {
  309.         zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
  310.         danach[i]  /= 0xd8L;
  311.         zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
  312.         danach[i]  /= 0xd8L;
  313.         zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
  314.         zeile2[j++] = code[(int)(danach[i] / 0xd8L)];
  315.       }
  316.  
  317.       for (i=0;i<64;i++)
  318.         csequence = crctab[csequence>>8] ^ (((csequence&255)<<8) |
  319.                                                          (byte) zeile2[i]);
  320.  
  321.       /* package line number and crc into three radix216 bytes and add
  322.          to code line. */
  323.       danach[0] = ((long)(lfd_zeile & 0x1ff) << 14) | (csequence & 0x3fff);
  324.       zeile2[j++] = code[(int) (danach[0] % 0xd8L)];
  325.       danach[0] /= 0xd8L;
  326.       zeile2[j++] = code[(int) (danach[0] % 0xd8L)];
  327.       zeile2[j++] = code[(int) (danach[0] / 0xd8L)];
  328.  
  329.       add_crc2 (zeile2);
  330.       fprintf (raus, "%s", zeile2);
  331.  
  332.       /* conclude line with line separator. */
  333.       fprintf (raus, delimit);
  334.       lfd_zeile++; /* increase line counter. */
  335.     }
  336.  
  337.     if (!correct) /* put end indicator into output file. */
  338.     {
  339.       strupr (filename);
  340.       fprintf (raus, " stop_7+. (%s)%s", filename, delimit);
  341.     }
  342.     else
  343.     {
  344.       /* if we were creating correction file, complete it. */
  345.       fprintf (raus, " P00:%s", delimit);
  346.       fclose (raus);
  347.       crc_file (filename, "7P", " P00:\n", 0);
  348.       raus = fopen (filename, OPEN_APPEND_TEXT);
  349.       fprintf (raus, " stop_text.%s", delimit);
  350.     }
  351.  
  352.     if (endstr)
  353.       fprintf (raus, "%s%s", endstr, delimit);
  354.  
  355.     if (ferror(raus)) /* did any errors occur while writing? */
  356.     {
  357.       printf ("\n\007Write error. Break.\n");
  358.       fclose (rein);
  359.       return (1);
  360.     }
  361.  
  362.     /* OK. This part is done. */
  363.     fclose (raus);
  364.  
  365.   } /* end of for() */
  366.  
  367.   /* all parts done.
  368.      tell user about action. */
  369.   if (correct)
  370.     printf ("\nCorrection file '%s' compiled.\n\n", filename);
  371.   else
  372.   {
  373.     printf ("\n\nEncoding successful!\n\n");
  374.     if (fls)
  375.     {
  376.       if ((raus = fopen ("7plus.fls", OPEN_WRITE_TEXT)) == NULL)
  377.         return (14);
  378.       fnsplit (filename, NULL, NULL, _file, NULL);
  379.       fprintf (raus, "%d %s\n", parts, _file);
  380.       fclose (raus);
  381.     }
  382.   }
  383.   fclose (rein);
  384.   return (0);
  385. }
  386.